package com.jlf.core.engine.builder;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Enumeration;

/**
 * 自动生成器的类加载器
 *
 * @author wujr
 * 2023/7/9
 * @version 1.0
 * 【变更历史】
 * [wujr 2023/7/9 1.0 新增]
 */
public class AutoClassLoader extends ClassLoader{
    private ClassLoader defaultClassLoader;

    protected AutoClassLoader(ClassLoader parent) {
        super(parent);
    }

    public AutoClassLoader() {
        super();
    }

    public void setDefaultClassLoader(ClassLoader loader){
        this.defaultClassLoader = loader;
    }

    @Override
    public Class<?> loadClass(String name) throws ClassNotFoundException {
        try {
            return this.defaultClassLoader.loadClass(name);
        }catch(Exception e){
            return super.loadClass(name);
        }
    }

    @Override
    public URL getResource(String name) {
        try{
            return this.defaultClassLoader.getResource(name);
        }catch(Exception e) {
            return super.getResource(name);
        }
    }

    @Override
    public Enumeration<URL> getResources(String name) throws IOException {
        try{
            return this.defaultClassLoader.getResources(name);
        }catch(Exception e) {
            return super.getResources(name);
        }
    }

    @Override
    public InputStream getResourceAsStream(String name) {
        try{
            return this.defaultClassLoader.getResourceAsStream(name);
        }catch(Exception e) {
            return super.getResourceAsStream(name);
        }
    }

    @Override
    public void setDefaultAssertionStatus(boolean enabled) {
        this.defaultClassLoader.setDefaultAssertionStatus(enabled);
        super.setDefaultAssertionStatus(enabled);
    }

    @Override
    public void setPackageAssertionStatus(String packageName, boolean enabled) {
        this.defaultClassLoader.setPackageAssertionStatus(packageName, enabled);
        super.setPackageAssertionStatus(packageName, enabled);
    }

    @Override
    public void setClassAssertionStatus(String className, boolean enabled) {
        this.defaultClassLoader.setClassAssertionStatus(className, enabled);
        super.setClassAssertionStatus(className, enabled);
    }

    @Override
    public void clearAssertionStatus() {
        this.defaultClassLoader.clearAssertionStatus();
        super.clearAssertionStatus();
    }

    public Class<?> defineClass(String name, byte[] b) {
        // ClassLoader是个抽象类，而ClassLoader.defineClass 方法是protected的
        // 所以我们需要定义一个子类将这个方法暴露出来
        return super.defineClass(name, b, 0, b.length);
    }
}
